package thread.ch03;

import java.util.concurrent.TimeUnit;

/**
 * 对于服务器应用程序，确保无论是在开发阶段还是测试阶段，启动JVM时都使用-server命令行选项。
 * server模式的JVM会比client模式的JVM执行更多的优化
 * ，比如把没有在循环体中修改的变量提升到循环体外部；在开发环境（client模式的JVM）中可以工作的代码
 * ，可能会在部署环境（server模式的JVM）中失败。 <code>
 * while (!aSleep) {
		i++;
	}
 * </code> 与 <code>
 * if (!aSleep) {
		while (true) {
			i++;
		}
	}
 * </code>
 * 
 * 
 * 当一个域声明为volatile类型后，编译器在运行时会监视这个变量：它是共享的，而且对它的操作不会与其他的内存操作一起被重排序。
 * Volatile变量不会缓存在寄存器或者缓存在对其他处理器隐藏的地方。读取一个volatile类型的变量时，总会返回某一个线程所写入的最新值。
 * 访问volatile变量的操作不会加锁，也就不会引起执行线程的阻塞，这使得volatile变量相对于synchronized而言，只是轻量级同步机制。
 * 依赖volatile变量来控制状态可见性的代码，比使用锁的代码更脆弱，更难以理解。
 * 只有当volatile变量能够简化实现和同步策略的验证时，才使用它们。当验证正确性必须推断可见性问题时
 * ，应该避免使用volatile变量。正确使用volatile变量的方式包括
 * ：拥有确保它们所引用的对象状态的可见性，或者用于标识重要的生命周期事件（比如初始化或关闭）的发生。
 * 
 * @author Edgar Zhang
 * 
 */
public class CountSheep {
	// private static boolean aSleep;
	private volatile static boolean aSleep;

	public static void main(String[] args) throws InterruptedException {
		Thread backgroundThread = new Thread(new Runnable() {

			@Override
			public void run() {

				int i = 0;
				while (!aSleep) {
					i++;
				}
				// if (!aSleep) {
				// while (true) {
				// i++;
				// }
				// }
			}
		});
		backgroundThread.start();
		TimeUnit.SECONDS.sleep(1);
		aSleep = true;
	}

}
